package oh.how.easy.fck.services;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Hashtable;
import java.util.Map;
import oh.how.easy.fck.constants.FckEditorConstants;
import org.apache.tapestry5.Asset;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.slf4j.Logger;

/**
 * The main implementation.
 * @author Ville Virtanen
 */
public class FckEditorServiceImpl implements FckEditorService {

    private static final String NEW_LINE = System.getProperty("line.separator");
    private final Logger logger;
    private final Map<String, String> savedConfigurations;
    private final String commonConfiguration;
    private final String applicationContext;

    public FckEditorServiceImpl(Logger logger, @Inject @Symbol(FckEditorConstants.APPLICATION_CONTEXT) String context) {
        this.logger = logger;
        this.applicationContext = context;
        this.savedConfigurations = new Hashtable<String, String>();

        StringBuilder bldr = new StringBuilder();

        //Images
        bldr.append("FCKConfig.ImageUploadURL='fckeditor';");
        bldr.append(NEW_LINE);
        bldr.append("FCKConfig.ImageBrowserURL='../filemanager/browser/default/browser.html?Type=Image&Connector=fckeditor';");
        bldr.append(NEW_LINE);

        //Flashs
        bldr.append("FCKConfig.FlashUploadURL='fckeditor';");
        bldr.append(NEW_LINE);
        bldr.append("FCKConfig.FlashBrowserURL='../filemanager/browser/default/browser.html?Type=Flash&Connector=fckeditor';");
        bldr.append(NEW_LINE);

        //Links
        bldr.append("FCKConfig.LinkUploadURL='fckeditor';");
        bldr.append(NEW_LINE);
        bldr.append("FCKConfig.LinkBrowserURL='../filemanager/browser/default/browser.html?Connector=fckeditor';");
        bldr.append(NEW_LINE);

        commonConfiguration = bldr.toString();
    }

    @Override
    public void persistEditorConfiguration(Asset asset) {
        String key = getEditorConfigurationKey(asset);
        if(!savedConfigurations.containsKey(key)) {
            savedConfigurations.put(key, getConfigurationAsString(asset));
        }
    }

    @Override
    public void persistEditorConfiguration(Asset asset, String skinConfiguration) {
        String key = getEditorConfigurationKey(asset);
        if(!savedConfigurations.containsKey(key)) {
            String conf = getConfigurationAsString(asset);
            conf += NEW_LINE;
            conf += "FCKConfig.SkinPath = '";
            if(!applicationContext.equals("/")) {
                conf += applicationContext.substring(0, (applicationContext.length() - 1) );
            }
            conf += skinConfiguration + "';";
            savedConfigurations.put(key, conf);
        }
    }

    @Override
    public String getEditorConfigurationKey(Asset asset) {
        return asset.getResource().getPath();
    }

    @Override
    public String getEditorConfiguration(String configurationKey) {
        if(!savedConfigurations.containsKey(configurationKey)) {
            return "";
        }
        return savedConfigurations.get(configurationKey);
    }

    private String getConfigurationAsString(Asset configuration) {
        String conf = parseResourceToString( configuration.getResource() );
        String result = commonConfiguration + conf;
        return result;
    }

    private String parseResourceToString(Resource resource) {

        InputStream is = null;
        StringBuilder sb = new StringBuilder();

        try {

            is = resource.openStream();
            Reader r = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(r);
            String line = null;
            while((line=br.readLine()) != null){
                sb.append(line+NEW_LINE);
            }

        }catch(Exception ex){
            throw new RuntimeException(ex);
        }finally{
            try{
                is.close();
            }catch(Exception ex){}
        }

        return sb.toString();

    }

}